package lsl.leetCode.year2023.test0130;

/**
 * description:
 *
 * @author: liushengli
 * data: 2023/1/30
 */
public class test73 {
    public static void main(String[] args) {
        int[][] matrix = {{0, 1, 2, 0}, {3, 4, 5, 2}, {1, 3, 1, 5}};
        setZeroes2(matrix);
    }

    //方法一：使用标记数组
    // 时间复杂度：O(mn)
    // 空间复杂度：O(m+n)
    public static void setZeroes1(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean[] row = new boolean[m];
        boolean[] col = new boolean[n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 0) {
                    row[i] = col[j] = true;
                }
            }
        }
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (row[i] || col[j]) {
                    matrix[i][j] = 0;
                }
            }
        }
    }

    //方法二：使用两个标记变量
    // 我们可以用矩阵的第一行和第一列代替方法一中的两个标记数组,以达到O(1)的额外空间但这样会导致原数组的第一行和第一列被修改,无法记录它们是否原本包含0。
    // 时间复杂度：O(mn)
    // 空间复杂度：O(1)
    public static void setZeroes2(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        //因此我们需要额外使用两个标记变量分别记录第一行和第一列是否原本包含0。
        boolean rowFlag = false;
        boolean colFlag = false;
        for (int i = 0; i < n; i++) {
            //判断第一行是否包含0
            if (matrix[0][i] == 0) {
                rowFlag = true;
            }
        }

        for (int i = 0; i < m; i++) {
            //判断第一列是否包含0
            if (matrix[i][0] == 0) {
                colFlag = true;
            }
        }
        //从matrix[1][0]和matrix[0][1]开始记录
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = matrix[0][j] = 0;
                }
            }
        }

        //从第二行和第二列开始遍历修改
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (matrix[i][0] == 0 || matrix[0][j] == 0) {
                    matrix[i][j] = 0;
                }
            }
        }

        //判断第一行是否有0,存在的话就把第一行的数据都修改为0
        if (rowFlag) {
            for (int j = 0; j < n; j++) {
                matrix[0][j] = 0;
            }
        }

        //判断第一列是否有0,存在的话就把第一列的数据都修改为0
        if (colFlag) {
            for (int i = 0; i < m; i++) {
                matrix[i][0] = 0;
            }
        }
    }
}
